// -*- c-basic-offset: 2 default-tab-width: 2 indent-tabs-mode: t -*-
// vim: autoindent tabstop=2 noexpandtab shiftwidth=2 softtabstop=2
//===--------- Reactor.h - R virtual machine description --------------===//
//
//                          The VMKit project
//
// This file is distributed under the Purdue University Open Source
// License. See LICENSE.TXT for details.
//
//===------------------------------------------------------------------===//

#ifndef _REACTOR_H_
#define _REACTOR_H_

//===------------------ Header Includes ------------------===//

#include <llvm/GVMaterializer.h>

#include <cstring>
#include "util.h"
#include "vmkit/MethodInfo.h"
#include "vmkit/VirtualMachine.h"

#include "CVector.h"

//===------------------ End Header Includes -------------===//

namespace R {
	class RCompiler;
	class RModule;
	class Reactor;
	class Environment;
	class Evaluator;

	class ClArgumentsInfo {
	public:
		int argc; // Application Arguments count
		char** argv; // Application Arguments
		char* fname; // Code Filename to read
		int verbose; // Verbose mode level
		int debug; // debug
		int jitc; // use of jit
		int precompile; // precompile jit
		int chronometer; // compute execution time
		int skipBaseLibrary; // Skip loading of the base library

		void readArgs(Reactor *vm);

		static void printInformation();
		static void printVersion();
	};

	/// Reactor - An R Virtual Machine.
	///
	class Reactor : public vmkit::VirtualMachine {
	private:
		// Profiling vars
		struct timeval tbegin,tend;
		double texec;
		// end profiling vars

		uint64_t          curModuleId;
		CVector<RModule*> modules;

		RModule* allocateModule();

	public:
		Environment* toplevel;         // common
		uint64_t     toplevelIdx;      // common

		RCompiler* compiler;

		RModule* lookupModule(uint64_t moduleId);

		virtual void tracer(word_t closure);

		/// Reactor - Allocates a new R Virtual Machine.
		///
		Reactor(vmkit::BumpPtrAllocator& Alloc, 
						RCompiler* compiler, 
						vmkit::CompiledFrames** frames);

		virtual ~Reactor();

		/// argumentsInfo - The command line arguments given to the vm
		///
		ClArgumentsInfo argumentsInfo;

		/// runApplication - Runs the application with the given command line.
		/// User-visible function, inherited by the VirtualMachine class.
		///
		virtual void runApplication(int argc, char** argv);

		/// mainRStart - Start the application's execution in an R Thread.
		///
		static void mainRStart(Evaluator*);

	private:

		/// Virtual Inherited methods form VirtualMachine Class.
		///
		virtual void startCollection();
		virtual void endCollection();
		virtual void scanWeakReferencesQueue(word_t closure);
		virtual void scanSoftReferencesQueue(word_t closure);
		virtual void scanPhantomReferencesQueue(word_t closure);
		virtual void scanFinalizationQueue(word_t closure);
		virtual void addFinalizationCandidate(gc* obj);
		virtual size_t getObjectSize(gc* obj);
		virtual const char* getObjectTypeName(gc* obj);

		virtual bool enqueueReference(gc* _obj) {return false;}
		virtual void invokeFinalizer(gc* _obj) {}

		virtual void printMethod(vmkit::FrameInfo* FI, word_t ip, word_t addr);

		virtual void nullPointerException();
		virtual void stackOverflowError();

	};

} // end namespace R

#endif // protect from multiple inclusion 
